/*
 * Copyright 2009-2010 the original author or authors.
 *
 * Licensed under the Apache license, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.internna.iwebjtracker.services;

import org.internna.iwebjtracker.issue.model.Comment;
import org.internna.iwebjtracker.issue.model.Issue;
import org.internna.iwebjtracker.project.model.Module;
import org.internna.iwebjtracker.project.model.Project;
import org.internna.iwebjtracker.project.model.Version;
import org.internna.iwebjtracker.project.model.IWebJTrackerUser;
import org.internna.iwebjtracker.project.validation.Errors;
import org.internna.iwebmvc.model.Document;
import org.internna.iwebmvc.model.UUID;
import org.internna.iwebmvc.model.DomainEntity;

/**
 * Remote operations to handle the Issue entity.
 *
 * @author Jose Noheda
 * @since 1.0
 */
public interface IssueManager<M extends Module<P, M>, V extends Version<U, P, V>, U extends IWebJTrackerUser, P extends Project<?, M, V, U, P>, I extends Issue<M, V, U, P, C, I> & DomainEntity, C extends Comment<U, C, I>> {

    /**
     * Validates that the issue in question has all the mandatory fields and that every field
     * has consistent values.
     *
     * @param issue any
     * @return any
     */
    Errors validateIssue(I issue);

    /**
     * Creates a new issue and stores it in the persistent storage.
     *
     * @param issue any
     * @return null unless a new issue was generated
     */
    UUID createIssue(I issue);

    /**
     * Adds a vote from the current logged in user.
     *
     * @param issue any
     * @return true if the vote was counted
     */
    boolean vote(I issue);

    /**
     * Adds the current logged user as a watcher to the provided issue.
     *
     * @param issue any
     * @return true of the watch list has a new member
     */
    boolean watch(I issue);

    /**
     * Adds a comment from the current logged in user to the issue including
     * a potential parent comment (the provided comment would be a response).
     *
     * @param issue any (no operation if null)
     * @param comment any
     * @param chat any (no operation if empty)
     * @return true if the issue includes a the new comment
     */
    void comment(I issue, C comment, String chat);

    /**
     * Adds a previously uploaded file to this issue as an attachment.
     *
     * @param issue any
     * @param attachment any
     * @return the saved document
     */
    Document addAttachment(I issue, Document attachment);

    /**
     * Changes the developer assigned to the issue provided to the current user.
     *
     * @param issue any
     * @return the i18n status at the end
     */
    String assignToMe(I issue);

    /**
     * Establish a relation (of the provided type) between one issue an another.
     *
     * @param origin any
     * @param target any
     * @param type any
     * @return null or the i18n translated error
     */
    String linkWith(I origin, I target, Issue.Link type);

    /**
     * Closes an issue. Optionally include a closing comment or a provided end state.
     *
     * @param issue any (no action performed if null)
     * @param status any
     * @param comment any
     * @return the i18n error string or null
     */
    String closeIssue(I issue, Issue.ResolutionStatus status, String comment);

    /**
     * Sets a new target version for the issue.
     *
     * @param issue any
     * @param version any
     * @return the i18n key of the error or null
     */
    String applyTargetVersion(I issue, V version);

}
